#include <vector>
#include <iostream>

using namespace std;

void doubler(int &n) {
  // 当函数接受一个参数的时候，它接受的是这个参数的拷贝
  n = n * 2;
}

void doublerP(int *pn) {
  *pn *= 2;
}

void heavyWorkByValue(vector<int> v) {
  // 几乎不用这种方法
  // 按值传递参数
  // 如果 v 有 1000000 个元素的话
  cout << v.size() << endl;
}

void heavyWorkByRef(vector<int> &rv) {
  // 按引用传递参数
  cout << sizeof(rv) <<endl;
}

int *requestMemory() {
  // 向操作系统申请一块存储整数的内存
  int *addr = new int{10};
  return addr;
}


int main(int argc, char const *argv[])
{
  int a = 10;
  // 一个引用一旦定义好了，他就不能引用其它的东西了
  // 定义一个引用变量的时候，必需设置好它引用的是谁
  int &ra = a; // 引用

  // ra 叫做变量 a 的引用  
  cout << "ra = " << ra << endl;
  cout << "a = " << a << endl;

  cout << "After plus plus:" << endl;
  ++ra;
  cout << "ra = " << ra << endl;
  cout << "a = " << a << endl;

  int &ra1 = a;
  ++ra1;
  cout << "ra = " << ra << endl; // 12
  cout << "ra1 = " << ra1 << endl; // 12
  cout << "a = " << a << endl; // 12

  doubler(a);
  cout << "After doubler:" << endl;
  cout << "ra = " << ra << endl;
  cout << "ra1 = " << ra1 << endl;
  cout << "a = " << a << endl;

  int b = 11;
  
  ra = b; // ra 引用的变量的值 设置为 b 的值
   
  int &rb = b;

  // 为函数调用节约开销
  vector<int> v(2000000, 0);
  heavyWorkByValue(v);
  heavyWorkByRef(v);

  // 指针
  cout << "--------------------------" << endl;
  cout << "-------- Pointer ---------" << endl;

  // 我们如何创建一个变量保存 a 的位置呢？
  // int & - int 的引用
  // &a    - 取 a 的地址
  int *posA = &a; // &a 取变量 a 的地址

  int *posZ = nullptr; // 一个当前不指向任何位置的指针

  // hex 格式符
  cout << hex << posA << endl;
  cout << dec << *posA << endl;

  // 我们可以修改指针指向的内容
  posA = &b; // posA 就指向变量 b 了
  cout << "b = " << b <<endl;
  cout << *posA << endl;

  *posA = 15;
  // 对指针的修改就是对指向变量的修改；
  cout << "After assignment:" << endl;
  cout << "b = " << b <<endl;
  cout << *posA << endl;

  int c = 20;
  doublerP(&c);

  cout << "c = " << c << endl;

  // 无论是引用，还是指针，它只和挨着它最近的那个变量名绑定
  // 为什么要有指针
  // 是为了向操作系统动态申请资源
  // 最常见的一类资源就是内存


  for (int i = 0; i < 1000000; ++i) {
    int *p = requestMemory(); // 明确向操作系统要来的
    // 必要的操作
    delete p; // 把 p 指向的内存还给操作系统
  }
  
  vector<int> v {1, 2, 3, 4, 5};
  //             ^           ^
  auto pos = v.begin();

  // 迭代器是一种更高级的指针
  cout << *pos << endl;
  return 0;
}
